home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / b / b.lha / B / src / bint / b2tes.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-11-24  |  4.7 KB  |  215 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2.  
  3. /*
  4.   $Header: b2tes.c,v 1.4 85/08/22 16:57:17 timo Exp $
  5. */
  6.  
  7. #include "b.h"
  8. #include "b1obj.h"
  9. #include "b2par.h"
  10. #include "b2key.h"
  11. #include "b2syn.h"
  12. #include "b2nod.h"
  13. #include "b3err.h"
  14.  
  15. Forward bool conjunction(), disjunction();
  16. Forward parsetree right_test();
  17.  
  18. Visible parsetree test(q) txptr q; {
  19.     parsetree v;
  20.     skipsp(&tx);
  21.     if (!(conjunction(q, &v) || disjunction(q, &v))) v= right_test(q);
  22.     return v;
  23. }
  24.  
  25. Forward bool negation(), quantification();
  26. Forward parsetree tight_test();
  27.  
  28. Hidden parsetree right_test(q) txptr q; {
  29.     parsetree v;
  30.     skipsp(&tx);
  31.     if (!(negation(q, &v) || quantification(q, &v))) v= tight_test(q);
  32.     return v;
  33. }
  34.  
  35. Hidden bool conjunction(q, v) txptr q; parsetree *v; {
  36.     txptr ftx, ttx;
  37.     if (find(K_AND, q, &ftx, &ttx)) {
  38.         parsetree t;
  39.         t= tight_test(ftx); tx= ttx;
  40.         if (!conjunction(q, v)) *v= right_test(q);
  41.         *v= node3(AND, t, *v);
  42.         return Yes;
  43.     }
  44.     return No;
  45. }
  46.  
  47. Hidden bool disjunction(q, v) txptr q; parsetree *v; {
  48.     txptr ftx, ttx;
  49.     if (find(K_OR, q, &ftx, &ttx)) {
  50.         parsetree t;
  51.         t= tight_test(ftx); tx= ttx;
  52.         if (!disjunction(q, v)) *v= right_test(q);
  53.         *v= node3(OR, t, *v);
  54.         return Yes;
  55.     }
  56.     return No;
  57. }
  58.  
  59. Hidden bool negation(q, v) txptr q; parsetree *v; {
  60.     if (not_keyword()) {
  61.         *v= node2(NOT, right_test(q));
  62.         return Yes;
  63.     }
  64.     return No;
  65. }
  66.  
  67. Hidden bool quantification(q, v) txptr q; parsetree *v; {
  68.     bool some, each;
  69.     if ((some= some_keyword()) || (each= each_keyword()) || no_keyword()) {
  70.         parsetree t, e; typenode type;
  71.         txptr utx, vtx, ftx, ttx;
  72.         req(K_HAS, ceol, &utx, &vtx);
  73.         if (utx > q) {
  74.             parerr(MESS(2700, "HAS follows colon"));
  75.             /* as in: SOME i IN x: SHOW i HAS a */
  76.             utx= tx; vtx= q;
  77.         }
  78.         if (find(K_IN_quant, utx, &ftx, &ttx)) {
  79.             idf_cntxt= In_ranger;
  80.             t= idf(ftx); tx= ttx;
  81.             type= some ? SOME_IN : each ? EACH_IN : NO_IN;
  82.         } else if (find(K_PARSING, utx, &ftx, &ttx)) {
  83.             idf_cntxt= In_ranger;
  84.             t= idf(ftx);
  85.             if (nodetype(t) != COLLATERAL)
  86.                 pprerr(MESS(2701, "no collateral_identifier where expected"));
  87.             tx= ttx;
  88.             type= some ? SOME_PARSING : each ? EACH_PARSING
  89.                   : NO_PARSING;
  90.         } else {
  91.             parerr(MESS(2702, "neither IN nor PARSING found"));
  92.             utx= tx; vtx= q; t= NilTree; type= Nonode;
  93.         }
  94.         e= expr(utx); tx= vtx;
  95.         *v= node4(type, t, e, right_test(q));
  96.         return Yes;
  97.     }
  98.     return No;
  99. }
  100.  
  101. Forward bool cl_test(), order_test();
  102. Forward parsetree ref_or_prop();
  103.  
  104. Hidden parsetree tight_test(q) txptr q; {
  105.     parsetree v;
  106.     skipsp(&tx);
  107.     if (nothing(q, "test")) v= NilTree;
  108.     else if (!(cl_test(q, &v) || order_test(q, &v))) {
  109.         if (is_expr(Char(tx))) v= ref_or_prop(q);
  110.         else {
  111.             parerr(MESS(2703, "no test where expected"));
  112.             v= NilTree;
  113.         }
  114.     }
  115.     upto_test(q);
  116.     return v;
  117. }
  118.  
  119. Hidden bool cl_test(q, v) txptr q; parsetree *v; {
  120.     txptr tx0= tx;
  121.     if (open_sign()) { /* (expr) or (test) */
  122.         txptr ftx, ttx, tx1;
  123.         tx1= tx;
  124.         req(")", q, &ftx, &ttx); tx= ttx;
  125.         skipsp(&tx);
  126.         if (!Text(q)) {
  127.             tx= tx1;
  128.             *v= compound(ttx, test);
  129.             return Yes;
  130.         }
  131.     }
  132.     tx= tx0;
  133.     return No;
  134. }
  135.  
  136. Forward typenode relop();
  137.  
  138. Hidden bool order_test(q, v) txptr q; parsetree *v; {
  139.     txptr ftx;
  140.     if (findrel(q, &ftx)) {
  141.         typenode r;
  142.         *v= singexpr(ftx);
  143.         do {
  144.             r= relop();
  145.             if (!findrel(q, &ftx)) ftx= q;
  146.             *v= node3(r, *v, singexpr(ftx));
  147.         } while (ftx < q);
  148.         return Yes;
  149.     }
  150.     return No;
  151. }
  152.  
  153. Hidden typenode relop() {
  154.     skipsp(&tx);
  155.     return
  156.         at_most_sign()        ? AT_MOST :
  157.         unequal_sign()        ? UNEQUAL :
  158.         at_least_sign()        ? AT_LEAST :
  159.         equals_sign()        ? EQUAL :
  160.         less_than_sign()    ? LESS_THAN :
  161.         greater_than_sign()    ? GREATER_THAN :
  162.         /* psyserr */          Nonode;
  163. }
  164.  
  165. /* refined_test or proposition */
  166.  
  167. Forward parsetree dyadic_proposition();
  168.  
  169. Hidden parsetree ref_or_prop(q) txptr q; {
  170.     value t1;
  171.     txptr tx0= tx;
  172.     if (tag_operator(q, &t1)) {
  173.         value t2;
  174.         skipsp(&tx);
  175.         if (!Text(q)) return node2(TAG, t1);
  176.         if (tag_operator(q, &t2)) {
  177.             skipsp(&tx);
  178.             if (!Text(q))
  179.                 return node4(MONPRD, t1, node2(TAG, t2), Vnil);
  180.             release(t1); release(t2);
  181.             return (tx= tx0, unp_test(q));
  182.         }
  183.         release(t1);
  184.         if (!dya_sign()) return (tx= tx0, unp_test(q));
  185.     }
  186.     return (tx= tx0, dyadic_proposition(q));
  187.  
  188. Visible bool dya_proposition= No;
  189.  
  190. Hidden parsetree dyadic_proposition(q) txptr q; {
  191.     parsetree v; value name;
  192.     dya_proposition= Yes;
  193.     v= singexpr(q);
  194.     if (!Text(q)) /* unparsed */
  195.         return v;
  196.     if (!tag_operator(q, &name)) {
  197.         parerr(MESS(2704, "no dyadic predicate where expected"));
  198.         name= Vnil;
  199.     }
  200.     return node5(DYAPRD, v, name, singexpr(q), Vnil);
  201. }
  202.  
  203. Hidden Procedure upto_test(q) txptr q; {
  204.     skipsp(&tx);
  205.     if (Text(q)) {
  206.         txptr ftx, ttx;
  207.         if (find(K_AND, q, &ftx, &ttx) || find(K_OR, q, &ftx, &ttx)) {
  208.             tx= ftx;
  209.             parerr(MESS(2705, "cannot determine priorities; use ( and ) to resolve"));
  210.         } else parerr(MESS(2706, "something unexpected following test"));
  211.         tx= q;
  212.     }
  213. }
  214.